package com.whfc.common.face.wheatSunshine;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.whfc.common.util.HttpUtil;
import com.whfc.common.util.JSONUtil;
import com.whfc.common.util.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @Description: 小麦阳光人脸识别接口
 * @author: xugcheng
 * @version: 1.0
 * @date: 2020/6/6 11:36
 */
public class WheatSunshineFaceApi {

    private static Logger logger = LoggerFactory.getLogger(WheatSunshineFaceApi.class);

    /**
     * 应用ID
     */
    private String appId;

    /**
     * 应用秘钥
     */
    private String appSecret;

    /**
     * 服务器地址
     */
    private String server;

    public WheatSunshineFaceApi(String appId, String appSecret, String server) {
        this.appId = appId;
        this.appSecret = appSecret;
        this.server = server;
    }


    /**
     * 创建设备
     *
     * @param deviceKey 设备序列号
     * @param name      设备名称
     */
    public FaceResult<String> deviceAdd(String deviceKey, String name) {
        String url = this.server + WheatSunshineConst.deviceAddUri;

        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);
        data.put("name", name);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("创建设备,url:{},body:{},response:{}", url, body, response);

        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;

    }

    /**
     * 更新设备
     *
     * @param deviceKey 设备序列号
     * @param name      设备名称
     */
    public FaceResult<String> deviceUpdate(String deviceKey, String name) {
        String url = this.server + WheatSunshineConst.deviceUpdateUri;

        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);
        data.put("name", name);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("更新设备,url:{},body:{},response:{}", url, body, response);

        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;

    }

    /**
     * 删除设备
     *
     * @param deviceKey 设备序列号
     */
    public FaceResult<String> deviceDel(String deviceKey) {
        String url = this.server + WheatSunshineConst.deviceDelUri;

        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("删除设备,url:{},data:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 查询设备
     *
     * @param deviceKey 设备序列号
     */
    public FaceResult<String> deviceQuery(String deviceKey) {
        String url = this.server + WheatSunshineConst.deviceQueryUri;

        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);

        String response = HttpUtil.doGet(url, this.customHeader(data), data);
        logger.info("查询设备,url:{},data:{},response:{}", url, data, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }


    /**
     * 设备人员授权
     *
     * @param deviceKey
     * @param personGuids
     * @return
     */
    public FaceResult<String> deviceAuthorization(String deviceKey, List<String> personGuids) {
        String url = this.server + WheatSunshineConst.deviceAuthorizationUri;
        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);
        data.put("personGuids", StringUtils.join(personGuids, WheatSunshineConst.separator));
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("设备人员授权,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 设备人员授权查询
     *
     * @param deviceKey
     * @return
     */
    public FaceResult<String> deviceAuthorizationQuery(String deviceKey) {
        String url = this.server + WheatSunshineConst.deviceAuthorizationQueryUri;
        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doGet(url, this.customHeader(data), data);
        logger.info("设备人员授权查询,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 设备人员取消授权
     *
     * @param deviceKey
     * @param personGuid
     * @return
     */
    public FaceResult<String> deviceAuthorizationCancel(String deviceKey, String personGuid) {
        String url = this.server + WheatSunshineConst.deviceAuthorizationCancelUri;
        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);
        data.put("personGuid", personGuid);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("设备人员取消授权,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 设备人员取消授权
     *
     * @param deviceKey
     * @param personGuids
     * @return
     */
    public FaceResult<String> deviceAuthorizationCancel(String deviceKey, List<String> personGuids) {
        String url = this.server + WheatSunshineConst.deviceAuthorizationCancelBatchUri;
        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);
        data.put("personGuids", StringUtils.join(personGuids, WheatSunshineConst.separator));
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("设备人员取消授权,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }


    /**
     * 设备注册模式下发
     *
     * @param deviceKey
     * @param personGuid
     * @param type       1.读卡 2拍照 3身份证
     * @return
     */
    public FaceResult<String> deviceMode(String deviceKey, String personGuid, Integer type) {
        String url = this.server + WheatSunshineConst.deviceModeUri;
        Map<String, String> data = new HashMap<>();
        data.put("deviceKey", deviceKey);
        data.put("personGuid", personGuid);
        data.put("type", String.valueOf(type));
        String body = JSONUtil.toString(data);
        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("设备注册模式下发,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 设备开门
     *
     * @param deviceKey
     * @return
     */
    public FaceResult<String> deviceOpenDoor(String deviceKey) {
        String url = this.server + WheatSunshineConst.deviceOpenDoorUri;
        Map<String, String> data = new HashMap<>();
        data.put("deviceKeyList", JSONArray.toJSONString(Arrays.asList(deviceKey)));
        String body = JSONUtil.toString(data);
        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("设备开门,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }


    /**
     * 添加人员
     *
     * @param name
     * @return
     */
    public FaceResult<String> personAdd(String name) {
        String url = this.server + WheatSunshineConst.personAddUri;
        Map<String, String> data = new HashMap<>();
        data.put("name", name);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("新增人员,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 查询人员
     *
     * @param guid
     * @return
     */
    public FaceResult<String> personQuery(String guid) {
        String url = this.server + WheatSunshineConst.personQueryUri;

        Map<String, String> data = new HashMap<>();
        data.put("guid", guid);

        String response = HttpUtil.doGet(url, this.customHeader(data), data);
        logger.info("查询人员,url:{},data:{},response:{}", url, data, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 删除人员
     *
     * @param guid
     * @return
     */
    public FaceResult<String> personDel(String guid) {
        String url = this.server + WheatSunshineConst.personDelUri;
        Map<String, String> data = new HashMap<>();
        data.put("guid", guid);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("删除人员,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 更新人员
     *
     * @param guid
     * @param name
     * @return
     */
    public FaceResult<String> personUpdate(String guid, String name) {
        String url = this.server + WheatSunshineConst.personUpdateUri;
        Map<String, String> data = new HashMap<>();
        data.put("guid", guid);
        data.put("name", name);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("更新人员,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 人员照片注册
     *
     * @param guid
     * @param imgBase64
     * @return
     */
    public FaceResult<String> personFaceAdd(String guid, String imgBase64) {
        String url = this.server + WheatSunshineConst.personFaceAddUri;
        Map<String, String> data = new HashMap<>();
        data.put("guid", guid);
        data.put("img", imgBase64);
        data.put("type", "1"); //1-普通照片 2-红外照片
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("人员照片注册,url:{}", url);
        return JSON.parseObject(response, FaceResult.class);
    }

    /**
     * 人员照片查询
     *
     * @param guid
     * @return
     */
    public FaceResult<String> personFaceQuery(String guid) {
        String url = this.server + WheatSunshineConst.personFaceQueryUri;
        Map<String, String> data = new HashMap<>();
        data.put("guid", guid);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doGet(url, this.customHeader(data), data);
        logger.info("人员照片查询,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 人员设备授权
     *
     * @param guid
     * @param deviceKeys
     * @return
     */
    public FaceResult<String> personmandate(String guid, String deviceKeys) {
        String url = this.server + WheatSunshineConst.personMandateUri;
        Map<String, String> data = new HashMap<>();
        data.put("guid", guid);
        data.put("deviceKeys", deviceKeys);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("人员设备授权,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 人员设备取消授权
     *
     * @param guid
     * @param deviceKey
     * @return
     */
    public FaceResult<String> personmandateCancel(String guid, String deviceKey) {
        String url = this.server + WheatSunshineConst.personMandateCancelUri;
        Map<String, String> data = new HashMap<>();
        data.put("guid", guid);
        data.put("deviceKey", deviceKey);
        String body = JSONUtil.toString(data);

        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("人员设备取消授权,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }


    /**
     * 新增回调
     *
     * @param callbackType 1.拍照回调 2.读卡回调 3.考勤回调
     * @param callbackUrl
     * @return
     */
    public FaceResult<String> callbackAdd(Integer callbackType, String callbackUrl) {
        String url = this.server + WheatSunshineConst.callbackAddUri;
        Map<String, String> data = new HashMap<>();
        data.put("callbackType", String.valueOf(callbackType));
        data.put("callbackUrl", callbackUrl);
        String body = JSONUtil.toString(data);
        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("新增回调,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 更新回调
     *
     * @param callbackType
     * @param callbackUrl
     * @return
     */
    public FaceResult<String> callbackUpdate(Integer callbackType, String callbackUrl) {
        String url = this.server + WheatSunshineConst.callbackUpdateUri;
        Map<String, String> data = new HashMap<>();
        data.put("callbackType", String.valueOf(callbackType));
        data.put("callbackUrl", callbackUrl);
        String body = JSONUtil.toString(data);
        String response = HttpUtil.doPost(url, body, this.customHeader(data));
        logger.info("更新回调,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }

    /**
     * 查询回调
     *
     * @param callbackType
     * @return
     */
    public FaceResult<String> callbackQuery(Integer callbackType) {
        String url = this.server + WheatSunshineConst.callbackQueryUri;
        Map<String, String> data = new HashMap<>();
        if (callbackType != null) {
            data.put("callbackType", String.valueOf(callbackType));
        }
        String body = JSONUtil.toString(data);
        String response = HttpUtil.doGet(url, this.customHeader(data), data);
        logger.info("查询回调,url:{},body:{},response:{}", url, body, response);
        FaceResult<String> result = JSON.parseObject(response, FaceResult.class);
        return result;
    }


    /**
     * 自定义header
     *
     * @param data
     * @return
     */
    private Map<String, String> customHeader(Map<String, String> data) {
        Map<String, String> headers = new HashMap<>(2);
        headers.put("appid", this.appId);
        headers.put("sign", this.sign(data));
        headers.put("pass", "RVyzuoUw");
        System.out.println(JSONObject.toJSONString(headers));
        return headers;
    }

    /**
     * 计算签名
     *
     * @param params 参数列表
     * @return
     */
    public String sign(Map<String, String> params) {


        Map<String, String> signMap = new HashMap<>(params);
        signMap.put("appid", this.appId);
        //拼接键值对
        List<String> stringSignList = new ArrayList<>();
        for (Map.Entry<String, String> entry : signMap.entrySet()) {
            stringSignList.add(String.format("%s=%s", entry.getKey(), entry.getValue()));
        }
        //排序
        Collections.sort(stringSignList);
        stringSignList.add(String.format("secret=%s", this.appSecret));

        //签名字符串
        StringBuffer stringSignTemp = new StringBuffer();
        for (String stringSign : stringSignList) {
            if (stringSignTemp.length() > 0) {
                stringSignTemp.append("&");
            }
            stringSignTemp.append(stringSign);
        }
        String sign = MD5Util.md5Encode(stringSignTemp.toString()).toUpperCase();
        logger.info("appId:{},sign:{}", appId, sign);
        return sign;
    }


    public static void main(String[] args) {
        WheatSunshineFaceApi wheatSunshineFaceApi = new WheatSunshineFaceApi("UK2KKhbc","3778e6a407adedba4dbeb033c3a2516fd61906df","http://sg.4000750222.com/hardware");
        wheatSunshineFaceApi.deviceOpenDoor("dd32fcebf1d68b1f");
    }
}
